#include <bits/stdc++.h>
using namespace std;
const int N = 1e4 + 10, M = 5e4 + 10;
vector<int> adj[N];
int dfn[N], low[N], deg[N], sz[N];
int scc[N], sccidx;  // 节点i所在SCC的编号
bool instack[N];
int n, m;
int dfncnt;
stack<int> s;
void tarjan(int u) {
  dfn[u] = low[u] = ++dfncnt;
  s.push(u);
  instack[u] = true;
  for (auto v : adj[u]) {
    if (!dfn[v]) {  // v未被搜索过
      tarjan(v);
      low[u] = min(low[u], low[v]);
    } else if (instack[v])  // v在栈中
      low[u] = min(low[u], dfn[v]);
  }
  int k = -1;  // 不必担心，k在使用前一定是赋值了的
  if (low[u] == dfn[u]) {
    ++sccidx;
    do {
      k = s.top();
      s.pop();
      instack[k] = false;
      scc[k] = sccidx;
      sz[sccidx]++;
    } while (u != k);
  }
}
int main() {
  cin >> n >> m;
  for (int i = 0; i < m; ++i) {
    int u, v;
    cin >> u >> v;
    adj[u].push_back(v);
  }
  for (int i = 1; i <= n; ++i) {
    if (!dfn[i]) tarjan(i);
  }
  for (int u = 1; u <= n; ++u) {
    for (auto v : adj[u]) {
      if (scc[u] != scc[v]) {
        deg[scc[u]]++;  // 遍历点并记录出度
      }
    }
  }

  bool id = 0;
  for (int i = 1; i <= sccidx; ++i) {
    if (!deg[i]) {
      if (id) {
        // 两次出现出度为0的点，直接输出0
        puts("0");
        return 0;
      }
      id = i;
    }
  }

  cout << sz[id] << endl;
}
